package mt.filter;

import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import mt.Order;
import mt.comm.ServerSideMessage;
import mt.dummy.ServerCommDummy;
import mt.filter.clock.DummyClock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class AnalyticsFilterPrintStatisticsWithManualClockTest {

	private final ByteArrayOutputStream outContent =  new ByteArrayOutputStream();
	private DummyClock clock;
	private ServerCommDummy serverCommDummy;
	private AnalyticsFilter analyticsFilter;

	@Before
	public void setUpFilter() {
		
		clock = new DummyClock();
		serverCommDummy = new ServerCommDummy();
		analyticsFilter = new AnalyticsFilter(serverCommDummy, clock);

		// Three messages are going to be created
		for (int i = 0; i < 3; i++) {
			serverCommDummy.getListOfMessages().add(new ServerSideMessage() {

				@Override
				public Type getType() {
					return Type.NEW_ORDER;
				}

				@Override
				public String getSenderNickname() {
					return "batata";
				}

				@Override
				public Order getOrder() {
					return Order.createBuyOrder(null, null, 0, 0);
				}
			});
		}

		System.setOut(new PrintStream(outContent));
		analyticsFilter.start();
	}

	@After
	public void cleanUpStreams() {
		System.setOut(null);
	}

	/**
	 * Tests the filter with a manual clock(DummyClock).
	 */
	@Test
	public void testprintStatisticsMessageDummyClock() {

		for (int i = 0; i < 30; i++)
			clock.incrementTick();

		// No statistics must be shown, since the first minute has not been reached
		assertEquals("", outContent.toString()); 

		// Got the first two messages from the queue
		analyticsFilter.getNextMessage();
		analyticsFilter.getNextMessage();

		// 1 minute = 60 ticks
		for (int i = (int) clock.getTime(); i < 60; i++)
			clock.incrementTick();

		assertEquals("Average orders received per minute: 2.0"
						+ System.lineSeparator(), outContent.toString());

		// Cleans up the old messages on byteArray
		outContent.reset();

		// Situation when the next minute has not been hit
		for (int i = (int) clock.getTime(); i < 100; i++)
			clock.incrementTick();

		// Anything should be printed, since we haven't reached the 2 minutes yet
		assertEquals("", outContent.toString());

		outContent.reset();

		// Get the third message from the queue
		analyticsFilter.getNextMessage();

		// 2 seconds have been hit
		for (int i = (int) clock.getTime(); i < 120; i++)
			clock.incrementTick();

		assertEquals("Average orders received per minute: 1.0"
						+ System.lineSeparator(), outContent.toString());

	}

}
